perm filename 106NTC[1,RWF]1 blob sn#728170 filedate 1983-10-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00005 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	Strings
C00004 00003	Definitions
C00006 00004
C00009 00005	A pure function is very easy to test separately from the rest of the program.
C00013 ENDMK
C⊗;
Strings

"What do you get when you cross a Neptunian with a Uranian?  Somebody who
steals space ships, but can't drive them."

What happens when you cross characters and arrays?  Well, on Uranus they tried
to do it by letting arrays be characters.  When they found that to handle
2 by 2 arrays of real numbers as characters they would need more keys on each
keyboard than there are electrons in the universe, they quadrupled the tentacle
tax to pay for it.  The dodecapods rebelled, the government fell, and computers
were outlawed.  We do it differently.

Our written languages are based on sequences of characters: words, sentences,
paragraphs, books, titles, part numbers, license plates, mathematical formulas,
even computer programs.  In Pascal, values like these are kept in arrays of 
characters.  Such arrays are called strings.

Definitions

In describing a programming language, it is convenient to factor the definition
into syntax, semantics, and pragmatics.  Syntax is the grammar of the language;
it defines which texts are in the language, and how each program is subdivided
into meaningful parts.  Semantics defines a meaning for each syntactically correct
program, usually by saying what sequence of actions the program performs. 
Pragmatics is concerned with usage and practicality.  Pragmatic details of a
language include the cost in time or money of executing a program, the resources
(such as memory capacity) the computer must have, and the precision with which
calculation is done.

The syntactic definition of the part of Pascal already introduced follows

Program:


	PROGRAM		name		(OUTPUT);


		variable
		declaration     ;


	BEGIN		command         ;	END.



Name:


	letter		letter


			digit


			underline



Variable Declaration:


	VARIABLE	name     	,	:	INTEGER


							REAL



Command:


	WRITE	   (	operand     ,		)


	WRITELN


	FOR variable := expr TO expr DO command


	BEGIN	command		;	END


WRITE(I), where I is an integer-valued expression, prints the value of I,
preceded by enough blanks to make a total of 12 characters.

*************

WRITE(R), where R is a real-valued expression, prints the value of R....

WRITELN by itself adds a carriage return to the output file; subsequent printing
will be on a new line.

WRITE(A,B,C) and WRITELN(A,B,C) abbreviate

	BEGIN		BEGIN
	WRITE(A);	WRITE(A);
	WRITE(B);	WRITE(B);
	WRITE(C);	WRITE(C);
	END		WRITELN
			END

The files created by WRITE and WRITELN should have no more than 132 characters
per line for printing, and no more than 80 per line for display.

Rule of Good Programming Practice: Check that your program, by using WRITELN,
prevents accumulation of oversized output lines.

Expressions include constants and variables.  They also can be built up from smaller 
expressions using standard operations and functions.  If A and B are two 
expressions, and a and b are their respective numerical values, the first column 
in the following table lists expressions that can be built from A and B; the
second column gives the value of the built-up expression


	Expression		Value

	A + B			a + b
	A - B			a - b
	A * B			a x b
	A / B			a / b (an error if b = 0)
	+A			a
	-A			-a
	A DIV B			the integer part of a / b; a and b must be integers
	(A)			a
	ABS(A)			|a|
	SQR (A)			a
	SIN (A)			sine(a)
	COS (A)			cosine(a)
	LN (A)			log (a) (an error if a≤0)
	EXP (A)			e
	SQRT (A)		 a (an error if a<0)
	ARCTAN (A)		tan(a) in the range -π/2, π/2







A pure function is very easy to test separately from the rest of the program.
If it works with numbers, we can try it with constant arguments C1,C2,...Cn
by incorporating the function definition in this program:

PROGRAM....(OUTPUT);

definition of function F;

	BEGIN

	WRITELN(C1,C2,...,Cn,F(C1,C2,...,Cn))

	END.


The penultimate line can be repeated with as many different argument values as
needed, or one can iterate:

FOR I:= 1 to N DO
	
	BEGIN

	READ(X1,X2,...,XN);

	WRITELN(X1,X2,...,XN,F(X1,X2,...,XN)

	END

Such a program is called a driver; its only purpose is to test a pure function on
data for which the correct result is known.

Conversely, it is easy to test the main program without the correct definition of
the pure function, replacing the function's definition by some easy function.
If the main program is designed to form the sum F(1)+F(2)+...+F(100), and the
correct definition of F is difficult, we can test the summation and the printing
format by using the function F(X)=X, this way:

PROGRAM P(OUTPUT);

VAR

FUNCTION F(I:INTEGER:REAL;

	BEGIN

	F:=I

	END;

BEGIN

SUM:=0.0

FOR J:= 1 TO 100 DO

	SUM:= SUM + F(J);

WRITELN SUM:6:2

END.


If the program prints 5050.00, we know that the main program is in good shape.
We have tested it using a stub in place of the correct subprogram; a stub goes
through the same motions as the absent subprogram, without necessarily giving
correct answers.

If the test of the master program requires that the subprogram give correct
answers, we can still test with a stub, but the stub now asks the user for help.
The declaration of the stub looks like:

FUNCTION F(X,Y:REAL):REAL;

BEGIN

WRITELN(TTY,'WHAT IS F IF X AND Y ARE',X,Y);

READ(TTY,X,Y)

(* FOR A MORE RELIABLE TERMINAL INPUT *)

(* SEE SECTION ON FILES               *)

END


Every part of a program under development can be tested separately, by using a
driver to substitute for its master program, and stubs to substitute for its
subprograms.  This technique allows a team to subdivide a programming project
in such a way that no bottlenecks impede the testing.

Reference:  Aron, The Programs Development Process.